package gui.extra.table;

import lib.model.EpisodeFile;
import lib.model.MovieFile;
import lib.model.Subtitle;
import lib.model.VideoFile;

import javax.swing.table.DefaultTableModel;
import java.util.ArrayList;
import java.util.List;

public class VideoTableModel extends DefaultTableModel {

    /**
     *
     */
    private static final long serialVersionUID = 4205143311042280620L;

    private Class<?>[] columnTypes;
    final boolean[] columnEditables;
    private boolean showOnlyFound = false;
    private List<VideoFile> rowList = new ArrayList<VideoFile>();

    public VideoTableModel(Object[][] data, Object[] columnNames) {
        super(data, columnNames);
        this.columnTypes = getColumnTypes(columnNames);
        this.columnEditables = getColumnEditables(columnNames);
    }

    private Class<?>[] getColumnTypes(Object[] columnNames) {
    	Class<?>[] columnTypes = new Class[columnNames.length];
        for (int i = 0; i < columnNames.length; i++) {
            if (SearchColumnName.SERIE.getColumnName().equals(columnNames[i])) {
                columnTypes[i] = SearchColumnName.SERIE.getC();
            } else if (SearchColumnName.FILENAME.getColumnName().equals(columnNames[i])) {
                columnTypes[i] = SearchColumnName.FILENAME.getC();
            } else if (SearchColumnName.FOUND.getColumnName().equals(columnNames[i])) {
                columnTypes[i] = SearchColumnName.FOUND.getC();
            } else if (SearchColumnName.SELECT.getColumnName().equals(columnNames[i])) {
                columnTypes[i] = SearchColumnName.SELECT.getC();
            } else if (SearchColumnName.OBJECT.getColumnName().equals(columnNames[i])) {
                columnTypes[i] = SearchColumnName.OBJECT.getC();
            } else if (SearchColumnName.WIP.getColumnName().equals(columnNames[i])) {
                columnTypes[i] = SearchColumnName.WIP.getC();
            } else if (SearchColumnName.SEASON.getColumnName().equals(columnNames[i])) {
                columnTypes[i] = SearchColumnName.SEASON.getC();
            } else if (SearchColumnName.EPISODE.getColumnName().equals(columnNames[i])) {
                columnTypes[i] = SearchColumnName.EPISODE.getC();
            } else if (SearchColumnName.TYPE.getColumnName().equals(columnNames[i])) {
                columnTypes[i] = SearchColumnName.TYPE.getC();
            } else if (SearchColumnName.TITLE.getColumnName().equals(columnNames[i])) {
                columnTypes[i] = SearchColumnName.TITLE.getC();
            } else if (SearchColumnName.SOURCE.getColumnName().equals(columnNames[i])) {
                columnTypes[i] = SearchColumnName.SOURCE.getC();
            }
        }
        return columnTypes;
    }

    private boolean[] getColumnEditables(Object[] columnNames) {
        boolean[] columnEditables = new boolean[columnNames.length];
        for (int i = 0; i < columnNames.length; i++) {
            if (SearchColumnName.SERIE.getColumnName().equals(columnNames[i])) {
                columnEditables[i] = SearchColumnName.SERIE.isEditable();
            } else if (SearchColumnName.FILENAME.getColumnName().equals(columnNames[i])) {
                columnEditables[i] = SearchColumnName.FILENAME.isEditable();
            } else if (SearchColumnName.FOUND.getColumnName().equals(columnNames[i])) {
                columnEditables[i] = SearchColumnName.FOUND.isEditable();
            } else if (SearchColumnName.SELECT.getColumnName().equals(columnNames[i])) {
                columnEditables[i] = SearchColumnName.SELECT.isEditable();
            } else if (SearchColumnName.OBJECT.getColumnName().equals(columnNames[i])) {
                columnEditables[i] = SearchColumnName.OBJECT.isEditable();
            } else if (SearchColumnName.WIP.getColumnName().equals(columnNames[i])) {
                columnEditables[i] = SearchColumnName.WIP.isEditable();
            } else if (SearchColumnName.SEASON.getColumnName().equals(columnNames[i])) {
                columnEditables[i] = SearchColumnName.SEASON.isEditable();
            } else if (SearchColumnName.EPISODE.getColumnName().equals(columnNames[i])) {
                columnEditables[i] = SearchColumnName.EPISODE.isEditable();
            } else if (SearchColumnName.TYPE.getColumnName().equals(columnNames[i])) {
                columnEditables[i] = SearchColumnName.TYPE.isEditable();
            } else if (SearchColumnName.TITLE.getColumnName().equals(columnNames[i])) {
                columnEditables[i] = SearchColumnName.TITLE.isEditable();
            } else if (SearchColumnName.SOURCE.getColumnName().equals(columnNames[i])) {
                columnEditables[i] = SearchColumnName.SOURCE.isEditable();
            }
        }
        return columnEditables;
    }

    public static VideoTableModel getDefaultVideoTableModel() {
        return new VideoTableModel(
                new Object[][]{},
                new String[]{
                        SearchColumnName.TYPE.getColumnName(), SearchColumnName.SERIE.getColumnName(),
                        SearchColumnName.FILENAME.getColumnName(),
                        SearchColumnName.TITLE.getColumnName(), SearchColumnName.SEASON.getColumnName(),
                        SearchColumnName.EPISODE.getColumnName(), SearchColumnName.WIP.getColumnName(),
                        SearchColumnName.FOUND.getColumnName(), SearchColumnName.SELECT.getColumnName(),
                        SearchColumnName.OBJECT.getColumnName()});
    }
    
    public static VideoTableModel getDefaultSubtitleTableModel() {
        return new VideoTableModel(
                new Object[][]{},
                new String[]{
                        SearchColumnName.FILENAME.getColumnName(),
                        SearchColumnName.SOURCE.getColumnName(),
                        SearchColumnName.SELECT.getColumnName(),
                        SearchColumnName.OBJECT.getColumnName()});
    }

    public void addRows(List<VideoFile> l) {
        for (VideoFile e : l) {
            addRow(e);
        }
    }

    public void addRow(VideoFile videoFile) {
        if (!rowList.contains(videoFile)){
            rowList.add(videoFile);
        }

        if ((showOnlyFound && videoFile.getMatchingSubs().size() > 0)
                || (!showOnlyFound)) {
            int cCount = getColumnCount();
            Object[] row = new Object[cCount];
            String columnName;
            for (int i = 0; i < cCount; i++) {
                columnName = this.getColumnName(i);
                if (SearchColumnName.SERIE.getColumnName().equals(columnName)) {
                    if (videoFile instanceof EpisodeFile) {
                        row[i] = ((EpisodeFile) videoFile).getShow();
                    } else if (videoFile instanceof MovieFile) {
                        row[i] = ((MovieFile) videoFile).getTitle();
                    }
                } else if (SearchColumnName.FILENAME.getColumnName().equals(columnName)) {
                    row[i] = videoFile.getFilename();
                } else if (SearchColumnName.FOUND.getColumnName().equals(columnName)) {
                    row[i] = videoFile.getMatchingSubs().size();
                } else if (SearchColumnName.SELECT.getColumnName().equals(columnName)) {
                    row[i] = false;
                } else if (SearchColumnName.OBJECT.getColumnName().equals(columnName)) {
                    row[i] = videoFile;
                } else if (SearchColumnName.WIP.getColumnName().equals(columnName)) {
                    if (videoFile instanceof EpisodeFile)
                        row[i] = ((EpisodeFile) videoFile).getBierEpisode().getWippercentage();
                } else if (SearchColumnName.SEASON.getColumnName().equals(columnName)) {
                    if (videoFile instanceof EpisodeFile)
                        row[i] = ((EpisodeFile) videoFile).getSeason();
                } else if (SearchColumnName.EPISODE.getColumnName().equals(columnName)) {
                    if (videoFile instanceof EpisodeFile)
                        row[i] = ((EpisodeFile) videoFile).getEpisodeNumbers().get(0);
                } else if (SearchColumnName.TYPE.getColumnName().equals(columnName)) {
                    row[i] = videoFile.getVideoType();
                } else if (SearchColumnName.TITLE.getColumnName().equals(columnName)) {
                    if (videoFile instanceof EpisodeFile)
                        row[i] = ((EpisodeFile) videoFile).getTitle();
                }
            }
            this.addRow(row);
        }
    }
    
    public void addRow(Subtitle subtitle) {
        int cCount = getColumnCount();
        Object[] row = new Object[cCount];
        String columnName;
        for (int i = 0; i < cCount; i++) {
            columnName = this.getColumnName(i);
            if (SearchColumnName.FILENAME.getColumnName().equals(columnName)) {
                row[i] = subtitle.getFilename();
            } else if (SearchColumnName.SELECT.getColumnName().equals(columnName)) {
                row[i] = false;
            } else if (SearchColumnName.OBJECT.getColumnName().equals(columnName)) {
                row[i] = subtitle;
            } else if (SearchColumnName.SOURCE.getColumnName().equals(columnName)) {
                row[i] = subtitle.getSubtitleSource();
            }
        }
        this.addRow(row);
    }

    public Class<?> getColumnClass(int columnIndex) {
        return columnTypes[columnIndex];
    }

    public boolean isCellEditable(int row, int column) {
        return columnEditables[column];
    }

    public Integer getSelectedCount(int column) {
        Integer k = 0;
        for (int i = 0; i < getRowCount(); i++) {
            if ((Boolean) getValueAt(i, column)) {
                k++;
            }
        }
        return k;
    }

    private void updateTable(){
        List<VideoFile> newRowList = new ArrayList<VideoFile>();
        newRowList.addAll(rowList);
        clearTable();
        addRows(newRowList);
    }

    public void clearTable() {
        while (getRowCount() > 0) {
            removeRow(0);
        }
        rowList.clear();
    }

    public void setShowOnlyFound(boolean showOnlyFound) {
        this.showOnlyFound = showOnlyFound;
        updateTable();
    }

    public boolean isShowOnlyFound() {
        return this.showOnlyFound;
    }
}

